/************************************************
 * constants
 ************************************************/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Ce = Components.Exception;

const nsISupports = Ci.nsISupports;
const ssIObserverable = Ci.ssIObserverable;
const ssIConfig = Ci.ssIConfig;
const ssISiteManager = Ci.ssISiteManager;
const ssITodoList = Ci.ssITodoList;
const ssIThemes = Ci.ssIThemes;


Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");

Components.utils.import('resource://superstart/xl.js');
Components.utils.import('resource://superstart/ssConfig.js');
Components.utils.import('resource://superstart/ssSiteManager.js');
Components.utils.import('resource://superstart/ssTodoList.js');
Components.utils.import('resource://superstart/ssThemes.js');


/**
 * The object for all interfaces in superstart
 */
function SuperStartObj() {
	this.logger = Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService);

	this.jsonDecode = function(text) {
		try {
			return JSON.parse(text);
		} catch (e) {
			this.logger.logStringMessage('** JSON parse [' + text + '] exception: ' + e + ' **');
			return {};
		}
	}
	this.jsonEncode = function(obj) {
		try {
			return JSON.stringify(obj);
		} catch (e) {
			return '';
		}
	}
	this.regulateUrl = function(url) {
		if (url != null && typeof(url) == 'string') {
			if (url.charAt(0) == '/') { // unix
				url = 'file://' + url;
			} else if (url.charAt(1) == ':' && (url.charAt(2) == '/' || url.charAt(2) == '\\')) { // windows
				url = 'file:///' + url;
			} else if (url.indexOf('://') == -1 && url.indexOf('about:') != 0) {
				url = 'http://' + url;
			}
		}
		return url;
	}
	this.getUrlFromFile = function(iF) {
		var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
		return ios.newFileURI(iF); 
	}

	/* copied from XPIProvider.jsm::extractFiles()
	 *  @param zr: zip reader
	 *  @param aDir: nsIFile of the directory
	 */
	this.extractFiles = function(zr, aDir) {
		function getTargetFile(aDir, entry) {
			let target = aDir.clone();
			entry.split("/").forEach(function(aPart) {
				target.append(aPart);
			});
			return target;
		}
		try {
			let entries = zr.findEntries("*/");
			while (entries.hasMore()) {
				var entryName = entries.getNext();
				let target = getTargetFile(aDir, entryName);
				if (!target.exists()) {
					try {
						target.create(Ci.nsILocalFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
					}
					catch (e) {
						return false;
					}
				}
			}
	
			entries = zr.findEntries(null);
			while (entries.hasMore()) {
				let entryName = entries.getNext();
				let target = getTargetFile(aDir, entryName);
				if (target.exists()) {
					continue;
				}
				zr.extract(entryName, target);
				target.permissions |= FileUtils.PERMS_FILE;
			}
			return true;
		} catch (e) {
			return false;
		}
	}

	xl.Observerable.call(this);
	ssConfig.call(this);
	ssSiteManager.call(this);
	ssTodoList.call(this);
	ssThemes.call(this);
}

SuperStartObj.prototype = {
	classID: Components.ID("{61af2fde-0514-46b6-ae57-149dd057d75f}"),
	/**
	 * .classDescription and .contractID are only used for backwards compatibility
	 * with Gecko 1.9.2 and XPCOMUtils.generateNSGetModule.
	 * in gecko 2, the information is in chrome.manifest
	 */
	classDescription: 'SuperStartCoreObject',
	contractID: '@enjoyfreeware.org/superstart;1',

	/**
	 * List all the interfaces your component supports.
	 * @note nsISupports is generated automatically; you don't need to list it.
	 */
	QueryInterface: XPCOMUtils.generateQI([ssIObserverable, ssIConfig, ssISiteManager, ssITodoList, ssIThemes]),


	/////////////////////////////////////////
	// utilies

	// below file I/O is copied from:
	// - https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO
	fileGetContents: function(iF) {
		var data = '';
		try {
			var is = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
			var cs = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
			is.init(iF, -1, 0, 0);
			cs.init(is, "UTF-8", 0, 0);
			
			let (s = {}) {
				let read = 0;
				do { 
					read = cs.readString(0xffffffff, s);
					data += s.value;
				} while (read != 0);
			}
			cs.close();
		} catch (e) {
		}
		
		return data;
	},

	filePutContents: function(iF, data) {
		var os = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
		
		os.init(iF, 0x02 | 0x08 | 0x20, FileUtils.PERMS_FILE, 0); 
		var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
		converter.init(os, "UTF-8", 0, 0);
		converter.writeString(data);
		converter.close();
	},
};

/**
 * XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
 * XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
 */
if (XPCOMUtils.generateNSGetFactory) {
	var NSGetFactory = XPCOMUtils.generateNSGetFactory([SuperStartObj]);
} else {
	var NSGetModule = XPCOMUtils.generateNSGetModule([SuperStartObj]);
}



